class BackgroundService {
  constructor() {
    this.collectedData = new Set();
    this.wal = [];
    chrome.storage.local.set({ wal: this.wal });
    this.encryptionKey = null;
    this.initEncryption();
  }

  initEncryption() {
    crypto.subtle
      .generateKey({ name: 'AES-GCM', length: 256 }, true, [
        'encrypt',
        'decrypt',
      ])
      .then((key) => (this.encryptionKey = key));
  }

  async encryptData(data) {
    const encoder = new TextEncoder();
    const iv = crypto.getRandomValues(new Uint8Array(12));
    const encrypted = await crypto.subtle.encrypt(
      { name: 'AES-GCM', iv },
      this.encryptionKey,
      encoder.encode(JSON.stringify(data))
    );
    return { iv, data: new Uint8Array(encrypted) };
  }

  handleMessages() {
    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      switch (message.type) {
        case 'newLinks':
          this.processNewLinks(message.data);
          break;
        case 'collectionStopped':
          this.finalizeCollection(message.reason);
          break;
      }
    });
  }

  processNewLinks(links) {
    chrome.storage.local.get(['wal'], (result) => {
      this.wal = result.wal || [];
      this.wal.push(...links);
      chrome.storage.local.set({ wal: this.wal });
    });
    links.forEach((link) => this.collectedData.add(link));
    this.checkMemoryUsage();
  }

  checkMemoryUsage() {
    if (performance.memory.usedJSHeapSize > 200 * 1024 * 1024) {
      this.finalizeCollection('memory_limit');
    }
  }

  triggerGC() {
    chrome.system.memory.getInfo((info) => {
      if (info.availableCapacity < 20) {
        this.finalizeCollection('memory_limit');
      }
    });
  }

  async finalizeCollection(reason) {
    const timestamp = new Date()
      .toISOString()
      .replace(/[^0-9]/g, '')
      .slice(0, 14);
    const filename = `douyin_${timestamp}.csv`;

    const formattedData = [...this.collectedData].map((link, index) => ({
      id: index + 1,
      url: `https://www.douyin.com/video/${link}`,
    }));
    const encryptedData = await this.encryptData(formattedData);
    const blob = new Blob([encryptedData.data], { type: 'text/csv' });

    chrome.downloads.download({
      url: URL.createObjectURL(blob),
      filename: filename,
      saveAs: true,
    });

    this.collectedData.clear();
    this.wal = [];
    chrome.storage.local.set({ wal: this.wal });
  }
}

// 初始化后台服务
const backgroundService = new BackgroundService();
backgroundService.handleMessages();
